from PyQt5.QtWidgets import QWidget,QLineEdit,QToolButton,QHBoxLayout
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5 import QtCore
from PyQt5.QtCore import QPoint,QRect
from PyQt5.QtGui import QPaintEvent,QMouseEvent,QPainter,QPolygon,QColor,QPen,QLinearGradient,QGradient,QFont


class SwitchButton(QWidget):
    def __init__(self,parent=None):
        super(SwitchButton, self).__init__(parent)
        self.setMouseTracking(True)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        self.offBkBegin = QColor(252,177,170)
        self.offBkEnd = QColor(254,179,172)

        self.onBkBegin = QColor(144,202,175)
        self.onBkEnd = QColor(146,204,177)

        self.slideOnBegin = QColor(0,142,89)
        self.slideOnEnd = QColor(2,144,91)

        self.slidOffBegin = QColor(192, 63, 60);
        self.slidOffEnd = QColor(194, 65, 62);

        self.mState = False
        self.mMouseDown = False
        self.mMouseMove = False
        self.mMouseUp = True
        self.resize(70,30)

    def mousePressEvent(self, event: QtGui.QMouseEvent):
        if event.button() == QtCore.Qt.LeftButton:
            self.mMouseDown = True
            self.mMouseUp = False
            self.firstPoint = event.pos()

    def mouseMoveEvent(self, event: QtGui.QMouseEvent):
        if self.mMouseDown:
            self.mMouseMove = True
            self.lastPoint = event.pos()
            self.repaint()


    def mouseReleaseEvent(self, event: QtGui.QMouseEvent):
        if self.mMouseDown:
            self.mMouseDown = False
            self.mMouseMove = False
            self.mMouseUp = True
            if event.pos().x() < self.width()/2.0:
                self.mState = False
            else:
                self.mState = True
            self.repaint()
    def paintEvent(self, event: QtGui.QPaintEvent):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing,True)
        self.drawPressBackground(painter)
        if self.mMouseMove:
            slideRect = QRect()
            diff = self.lastPoint.x() - self.firstPoint.x()
            left = 0
            if self.mState:
                left = (self.width() - self.height() + 4 - 2) + diff
                if left < 2:
                    slideRect.setLeft(2)
                elif left > (self.width() - self.height() + 4 - 2):
                    slideRect.setLeft(self.width() - self.height() + 4 - 2)
                else:
                    slideRect.setLeft(self.width() - self.height() + 4 - 2 +diff)
            else:
                left = diff
                if left < 2:
                    slideRect.setLeft(2)
                elif left > (self.width() - self.height() + 4 - 2):
                    slideRect.setLeft(self.width(),self.height() +4 -2)
                else:
                    slideRect.setLeft(diff)
            slideRect.setTop(2)
            slideRect.setWidth(self.height() - 4)
            slideRect.setHeight(self.height() - 4)

            painter.setPen(QtCore.Qt.NoPen)
            linGrad = QLinearGradient(self.rect().topLeft(),self.rect().bottomLeft())
            linGrad.setColorAt(0.0,self.slideOnBegin)
            linGrad.setColorAt(1.0,self.slideOnEnd)
            linGrad.setSpread(QGradient.PadSpread)
            painter.setBrush(linGrad)

            rrect = slideRect.intersected(self.rect())
            painter.drawEllipse(rrect)
            painter.setBrush(QtCore.Qt.NoBrush)
            painter.setPen(QColor(173,173,173,160))
            painter.drawEllipse(rrect)
        else:
            self.drawPressSlide(painter)

    def drawPressBackground(self,painter):
        path = QtGui.QPainterPath()
        path.moveTo(self.height()/2.0,0)
        path.arcTo(QtCore.QRectF(0,0,self.height(),self.height()),90,180)
        path.lineTo(self.width() - self.height()/2.0,self.height())
        path.arcTo(QtCore.QRectF(self.width()-self.height(),0,self.height(),self.height()),270,180)
        path.lineTo(self.height()/2.0,0)

        pathrect = QtGui.QPainterPath()
        pathrect.moveTo(0,0)
        pathrect.lineTo(0,self.height())
        pathrect.lineTo(self.width(),self.height())
        pathrect.lineTo(self.width(),0)
        pathrect.lineTo(0,0)

        interpath = path.intersected(pathrect)
        painter.setPen(QtCore.Qt.NoPen)
        linGrad = QLinearGradient(self.rect().topLeft(),self.rect().bottomLeft())
        startColor = QColor()
        endColor = QColor()
        if self.mState:
            startColor = self.onBkBegin
            endColor = self.onBkEnd
        else:
            startColor = self.offBkBegin
            endColor = self.offBkEnd
        linGrad.setColorAt(0.0,startColor)
        linGrad.setColorAt(1.0,endColor)
        linGrad.setSpread(QtGui.QGradient.PadSpread)
        painter.setBrush(linGrad)
        painter.drawPath(interpath)

        painter.setBrush(QtCore.Qt.Dense1Pattern)
        painter.setPen(QColor(72,72,72))
        tempFont = QtGui.QFont("微软黑雅",10,QtGui.QFont.Bold)
        painter.setFont(tempFont)
        xPos = 0
        yPos = self.height()/2 + QWidget.fontMetrics().height()/2
        sText = ""
        if self.mState:
            xPos = self.width()/5*2
            sText = "开"
        else:
            xPos = self.width()/5*3
            sText = "关"
        xPos -=  QWidget.fontMetrics().width(sText)/2
        painter.drawText(xPos,yPos,sText)

    def drawPressSlide(self,painter):
        slideRect = QRect()
        if self.mState:
            slideRect.setLeft(self.width() - self.height() + 4 - 2)
        else:
            slideRect.setLeft(2)
        slideRect.setTop(2)
        slideRect.setWidth(self.height() - 4)
        slideRect.setHeight(self.height() - 4)

        painter.setPen(QtCore.Qt.NoPen)
        linGrad = QLinearGradient(self.rect().topLeft(),self.rect().bottomLeft())
        if self.mState:
            linGrad.setColorAt(0.0,self.slideOnBegin)
            linGrad.setColorAt(1.0,self.slideOnEnd)
        else:
            linGrad.setColorAt(0.0,self.slidOffBegin)
            linGrad.setColorAt(1.0,self.slidOffEnd)
        linGrad.setSpread(QGradient.PadSpread)
        painter.setBrush(linGrad)
        rrect = slideRect.intersected(self.rect())
        painter.drawEllipse(rrect)

        painter.setBrush(QtCore.Qt.NoBrush)
        painter.setPen(QColor(173,173,173,160))
        painter.drawEllipse(rrect)


























